package au.com.iglootech.TaxTimeToolTip.ui.invoice;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import au.com.iglootech.TaxTimeToolTip.Entity.Company;
import au.com.iglootech.TaxTimeToolTip.Entity.Task;
import au.com.iglootech.TaxTimeToolTip.dao.GenericDao;
import au.com.iglootech.TaxTimeToolTip.service.CompanyService;
import au.com.iglootech.TaxTimeToolTip.service.InvoiceTaxService;
import au.com.iglootech.TaxTimeToolTip.ui.invoice.PerviewWindow.DoAction;
import au.com.iglootech.component.IGTTable;

import com.vaadin.data.Property;
import com.vaadin.data.util.BeanContainer;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.DateField;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Panel;
import com.vaadin.ui.Table;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window.Notification;

@Configurable(preConstruction = true)
@Component
@Scope("request")
public class InvoiceTaxTab extends CustomComponent {
	VerticalLayout mainLayout = new VerticalLayout();
	@Autowired
	private transient GenericDao genericDao;
	@Autowired
	private transient CompanyService companyService;
	@Autowired
	private transient InvoiceTaxService invoiceTaxService;

	private BeanContainer<String, Task> beans;
	private ComboBox companyComBox;
	private DateField startDate;
	private DateField endDate;
	private Set<Object> selectedItemIds = new HashSet<Object>();
	private Double totalGST;
	private TextArea detailsTextArea = new TextArea();

	private static final String COMPANY_NAME = "company.companyName";

	public InvoiceTaxTab() {
		this.setCaption("Invoice");
		beans = new BeanContainer<String, Task>(Task.class);
		beans.setBeanIdProperty("key");
		beans.addNestedContainerProperty(COMPANY_NAME);
		detailsTextArea.setWidth("500px");
		detailsTextArea.setHeight("80px");
		detailsTextArea.setCaption("Details");
		initContent();
	}

	private void initContent() {
		Panel panel = new Panel();
		// HorizontalPanel searchBar = new HorizontalPanel();

		// company combobox
		List<Company> companies = companyService.findAllCompany();
		companyComBox = new ComboBox("Company");
		companyComBox.setImmediate(true);
		companyComBox.setNullSelectionAllowed(false);
		for (Company company : companies) {
			companyComBox.addItem(company);
			companyComBox.setItemCaption(company, company.getCompanyName());
		}
		startDate = new DateField("Start Date");
		startDate.setDateFormat("dd/MM/yyyy");
		endDate = new DateField("End Date");
		endDate.setDateFormat("dd/MM/yyyy");
		HorizontalLayout searchBar = new HorizontalLayout();
		searchBar.setSpacing(true);
		searchBar.addComponent(companyComBox);
		searchBar.addComponent(startDate);
		searchBar.addComponent(endDate);
		panel.addComponent(searchBar);

		Button searchButton = new Button("Search");
		searchButton.addListener(new Button.ClickListener() {

			@Override
			public void buttonClick(ClickEvent arg0) {
				refreshTabel();
			}
		});

		panel.addComponent(searchButton);

		IGTTable taskTable = new IGTTable("Avaliable Task", beans);
		taskTable.setColumnHeader(COMPANY_NAME, "Company");
		taskTable.setWidth("100%");
		taskTable.setHeight("500px");
		taskTable.setColumnHeader("selected", "");
		taskTable.addGeneratedColumn("selected", new Table.ColumnGenerator() {
			@Override
			public Object generateCell(Table source, final Object itemId,
					Object columnId) {
				boolean selected = selectedItemIds.contains(itemId);
				/*
				 * When the chekboc value changes, add/remove the itemId from
				 * the selectedItemIds set
				 */
				final CheckBox cb = new CheckBox("", selected);
				cb.addListener(new Property.ValueChangeListener() {
					@Override
					public void valueChange(Property.ValueChangeEvent event) {
						if (selectedItemIds.contains(itemId)) {
							selectedItemIds.remove(itemId);
						} else {
							selectedItemIds.add(itemId);
						}
						countGotalGST();
					}
				});
				return cb;
			}
		});

		taskTable.setVisibleColumns(new String[] { "selected", "taskName",
				COMPANY_NAME, "period", "unit", "startDate" });

		HorizontalLayout buttons = new HorizontalLayout();
		buttons.setSpacing(true);
		Button previewButton = new Button("Preview");
		previewButton.addListener(new Button.ClickListener() {
			@Override
			public void buttonClick(ClickEvent event) {
				if (detailsTextArea.getValue() == null
						|| detailsTextArea.getValue().equals("")) {
					getWindow().showNotification(
							"Your have to input details for invoice.",
							Notification.TYPE_ERROR_MESSAGE);
				} else {
					List<Task> tasks = new ArrayList<Task>();
					totalGST = 0.00;
					for (Object itemId : selectedItemIds) {
						Task task = beans.getItem(itemId).getBean();
						totalGST += task.getPeriod() * task.getUnit();
						tasks.add(task);
					}
					PerviewWindow window = new PerviewWindow(getApplication(),
							generateInvoiceDate(
									(Company) companyComBox.getValue(),
									totalGST), tasks, new DoAction() {

								@Override
								public void afterInvoice() {
									getApplication().getMainWindow().showNotification("Your invoices has been changed.");
									// refresh tabel
									refreshTabel();
									
								}
							});
					getWindow().addWindow(window);
				}
			}
		});
		buttons.addComponent(previewButton);
		panel.addComponent(taskTable);
		// description
		panel.addComponent(detailsTextArea);
		panel.addComponent(buttons);

		mainLayout.addComponent(panel);
		this.setCompositionRoot(mainLayout);
	}

	public InvoiceDateVO generateInvoiceDate(Company company, Double totalGST) {
		return new InvoiceDateVO(company, totalGST,
				(String) detailsTextArea.getValue());
	}

	private void countGotalGST() {
		List<Task> tasks = new ArrayList<Task>();
		this.totalGST = 0.00;
		for (Object itemId : selectedItemIds) {
			Task task = beans.getItem(itemId).getBean();
			totalGST += task.getPeriod() * task.getUnit();
			tasks.add(task);
		}
	}

	private void refreshTabel() {
		List<Task> result = invoiceTaxService.findInvoiceTaskByCompany(
				(Company) companyComBox.getValue(),
				(Date) startDate.getValue(), (Date) endDate.getData());
		beans.removeAllItems();
		for (Task task : result) {
			beans.addBean(task);
		}
	}
}
